import { MessagePlugin } from 'tdesign-react'

const BASE_URL = import.meta.env.VITE_API_BASE_URL || '/'
const tenantId = import.meta.env.VITE_TENANT_ID || 1
const TIMEOUT = 10000
const SUCCESS_CODE = 0


const getToken = (): string | null => {
  return localStorage.getItem('token')
}

const refreshToken = async () => {
  const _refreshToken = localStorage.getItem('refreshToken')
  const res = await post<{
    accessToken: string,
    refreshToken: string,
  }>('/system/auth/refresh-token?refreshToken=' + _refreshToken)
  if (res) {
    localStorage.setItem('token', res.accessToken)
    localStorage.setItem('refreshToken', res.refreshToken)
  }
  return res
}

interface ApiResponse<T = unknown> {
  code: number;
  msg: string;
  data: T;
}

interface RequestOptions extends Omit<RequestInit, 'body'> {
  data?: Record<string, unknown>;
}

const request = async <T = unknown>(
  url: string,
  options: RequestOptions = {}
): Promise<T> => {
  const { method = 'GET', data, ...restOptions } = options

  const headers = new Headers({
    'Content-Type': 'application/json',
    ...restOptions.headers
  })

  const token = getToken()
  if (token) {
    headers.append('Authorization', `Bearer ${token}`)
  }

  if (tenantId) {
    headers.append('tenant-id', tenantId)
  }

  const controller = new AbortController()
  const timeoutId = setTimeout(() => controller.abort(), TIMEOUT)

  const fetchOptions: RequestInit = {
    method,
    headers,
    signal: controller.signal,
    ...restOptions
  }

  let fullUrl = `${BASE_URL}${url}`
  if (method.toUpperCase() === 'GET' && data) {
    const params = new URLSearchParams(data as Record<string, string>)
    fullUrl += `?${params.toString()}`
  }

  if (method.toUpperCase() !== 'GET' && data) {
    fetchOptions.body = JSON.stringify(data)
  }

  try {
    const response = await fetch(fullUrl, fetchOptions)
    clearTimeout(timeoutId)

    let result: ApiResponse<T>
    try {
      result = await response.json()
    } catch (error) {
      MessagePlugin.error(`服务器响应格式错误 (状态码: ${response.status})`)
      throw new Error(`Invalid JSON response from server. Status: ${response.status}`)
    }

    if (result.code !== SUCCESS_CODE) {
      if (result.code === 401) {
        // MessagePlugin.error(result.msg || '登录已过期，请重新登录');
        if (!localStorage.getItem('refreshToken')) {
          localStorage.removeItem('token')
          window.location.href = '/'
        }
        await refreshToken()
      } else if (result.msg === '无效的刷新令牌') {
        localStorage.removeItem('token')
        window.location.href = '/'
      } else {
        MessagePlugin.error(result.msg || '未知业务错误')
      }
      throw new Error(result.msg)
    }

    return result.data

  } catch (error) {
    clearTimeout(timeoutId)
    if (error instanceof Error && error.name === 'AbortError') {
      MessagePlugin.error('请求超时，请稍后重试')
    } else if (error instanceof TypeError && !error.message.includes('JSON')) {
      MessagePlugin.error('网络连接错误，请检查您的网络')
    }

    return Promise.reject(error)
  }
}

export const get = <T = unknown>(
  url: string,
  params?: Record<string, unknown>,
  options?: Omit<RequestOptions, 'data' | 'method'>
): Promise<T> => {
  return request<T>(url, { method: 'GET', data: params, ...options })
}

export const post = <T = unknown>(
  url: string,
  body?: Record<string, unknown>,
  options?: Omit<RequestOptions, 'data' | 'method'>
): Promise<T> => {
  return request<T>(url, { method: 'POST', data: body, ...options })
}

export const put = <T = unknown>(
  url: string,
  body?: Record<string, unknown>,
  options?: Omit<RequestOptions, 'data' | 'method'>
): Promise<T> => {
  return request<T>(url, { method: 'PUT', data: body, ...options })
}

export default request
